const _ = require('lodash')
const { log } = console
const getArea = (r) => {
  log(r)
  return Math.PI * Math.pow(r, 2)
}
// log(getArea(5))
// let getAreaWithMemory = _.memoize(getArea)
// log(getAreaWithMemory(4))
// log(getAreaWithMemory(4))
// log(getAreaWithMemory(4))
// 模拟memorize的实现

const memoize = (f) => {
  // 传入的是一个函数 f
  // 参数作为键 执行结果作为值
  // 根据参数判断有没有结果
  // 一个memoize对应一个函数 所以不需要操作函数名
  let cache = {}
  // 返回的也是函数 若有缓存直接读取缓存没有缓存直接执行函数
  return (...args) => {
    // arguments 是伪数组
    // args是真的数组
    // JSON.stringify转换成为字符串作为对象的键
    let key = JSON.stringify(args)
    // 值 缓存结果 或者 执行函数 主要是把伪数组转成数组给f传递一下
    cache[key] = cache[key] || f(args)
    // 如果是arguments需要f.apply(f,arguments)
    // 返回的函数的返回值是函数的执行结果
    return cache[key]
  }
}
let getAreaWithMemory = memoize(getArea)
const getBall = (r) => {
  log(r)
  return (Math.PI * Math.pow(r, 3) * 4) / 3
}
let getBallWithMemory = memoize(getBall)

log(getAreaWithMemory(4))
log(getAreaWithMemory(4))
log(getBallWithMemory(4))
log(getBallWithMemory(4))
